//
//  STDSGaussianBlurEffect.h
//  STDSRenderSDKIOS
//
//  Created by 陈学明 on 2023/4/3.
//

#ifndef STDSGaussianBlurEffect_h
#define STDSGaussianBlurEffect_h

#include "STDSBaseEffect.hpp"

/// 高斯模糊
class STDSGaussianBlurEffect: public STDSBaseEffect {
public:
    STDSGaussianBlurEffect() {
        mEffectType = STDSEffectTypeGaussianBlur;
    }
    ~STDSGaussianBlurEffect() {
//        printf("dealloc--STDSMosaicEffect\n");
    }
    
    void initGL() override {
        STDSBaseEffect::initGL();
    }
    
    void setIntArtuments(const char *name, int *intValue, int n) override {
        mRadius = *intValue;
    }
    
    void setFloatArguments(const char *name, float *floatValue, int n) override {
        mRadius = *floatValue;
    }
    
public:
    shared_ptr<STDSShaderProgram> getEffectProgram() {
        if (mBlurProgram == nullptr) {
            mBlurProgram = mContext->getProgram(kShaderSRCGaussianBlur);
        }
        return mBlurProgram;
    }
    
    void draw() override {
        auto program = this->getEffectProgram();
        if (program == nullptr) {
            return;
        }
        shared_ptr<STDSRenderTarget> rt = make_shared<STDSRenderTarget>(mTexture->getWidth(), mTexture->getHeight());
        rt->bindSelf();
        drawPass(0, program, mTexture);
        rt->restore();
        drawPass(1, program, rt->getTexture());
    }
    
    void drawPass(int orientation, shared_ptr<STDSShaderProgram> program, shared_ptr<STDSTexture> tex) {
        program->use();
        if (tex != nullptr) {
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, tex->getId());
            program->setUniform(program->getUniform("inputImageTexture"), 0);
        }
        program->setUniform(program->getUniform("radius"), mRadius);
        program->setUniform(program->getUniform("orientation"), orientation);
        program->setUniform2f(program->getUniform("size"), tex->getWidth(), tex->getHeight());
        mAtbRect.setPosVex(program->getAttrib("aPos"));
        mAtbRect.setPosTex(program->getAttrib("aTexCoord"));
        mAtbRect.draw();
        program->unuse();
    }

private:
    int mRadius{5};
    shared_ptr<STDSShaderProgram> mBlurProgram{nullptr};
};
#endif /* STDSGaussianBlurEffect_h */
